var Rson = require('Rson');
var ChessClass = require('Chess');
var SpriteLoader = require('RaiSpriteLoader');

var self;
var canSePlay;

cc.Class({
    extends: cc.Component,

    properties: {
        
        group: 'G',
        checkboard: cc.Sprite,
        wormNode: cc.Node,
        stateBar: cc.Sprite,
        eventLayer: cc.Node,
        pop: cc.Node,
        selectTerminalPanel: cc.Node,
        enemyTerminalPanel: cc.Node,
        enemyTeam: [cc.Sprite],
        myTeam: [cc.Sprite],
        wormTeam: [cc.Node],

        p_mass: cc.Prefab,
        p_click_b: cc.Prefab,
        p_click_g: cc.Prefab,
        p_fire: cc.Prefab,
        p_danger: cc.Prefab,
        p_honor: cc.Prefab,
        P_winback: cc.Prefab,
        P_rv: cc.Prefab,

        bullet: cc.Prefab,
        gamestart: false,
        vnum: 0,
        lnum: 0,
        terminalSwitch: [Boolean],//记录终端卡是否已使用
        myServerSize: 0,
        enemyServerSize: 0,
    },

    // use this for initialization
    onLoad: function () {
        cc.log("游戏场景加载");
        //plist的url
        this.plistUrl1 = 'Texture/Tex1'; 
        this.plistUrl2 = 'Texture/Tex2';
        this.currentChess = null;
        this.tips = cc.find('Canvas/fitLayer/stateBar/tips').getComponent(cc.Label);
        this.stateBar = cc.find('Canvas/fitLayer/stateBar').getComponent(cc.Sprite);
        this.buttonBar = cc.find('Canvas/fitLayer/buttonBar').getComponent('buttonBar');

        // 加载sound
        this.loadSound();

        this.btCallFunc = this.node.getComponent('btCallFunc');
        
        //this别名
        self = this;
        //音效开关
        canSePlay = cc.sys.localStorage.getItem('seSwitch');
        
        if(!cc.sys.localStorage.getItem('reloadLastGame'))
            {
                // 发送准备完成消息，开始全新对局
                this.sendData({'code':'20', 'name':'prepared', data:{}});
            }else{
                cc.sys.localStorage.setItem('reloadLastGame', '');
                // 发送准备完成消息，还原上一局对局
                this.sendData({'code':'1200', 'name':'repair', data:{}});
            }

        // 调度计时器每5秒检测一次websocket连接情况
        self.schedule(function(){
            if (!cc.webSocket || !(cc.webSocket instanceof WebSocket) || cc.webSocket.readyState !== WebSocket.OPEN)
                self.sendData({'code':'1000', 'name':'reConnect', data:{}});
        }, 5);

        // 吞噬标签
        this.swallowTag = false;
        // 添加场景点击反馈侦听
        let listenerObj = {
            event: cc.EventListener.TOUCH_ONE_BY_ONE,
            onTouchBegan: function (touch, event) {
                let pos = self.node.convertToNodeSpaceAR(touch.getLocation());
                self.showEffect('click'+self.group, pos.x, pos.y);

                // 吞噬标签为true则吞没事件,否则开启吞噬标签并计时恢复//作用是让每次有效点击之间间隔0.5秒
                if(self.swallowTag)
                    event.stopPropagation();
                else{
                    self.swallowTag = true;
                    self.scheduleOnce(function(){ self.swallowTag = false; }, 0.5);
                }

                return true; /*这里必须要写 return true*/
            },

            // onTouchMoved: function (touch, event) {
            //     //0.5秒显示一次点击特效防止卡顿
            //     if(self.swallowTag == true)
            //         return;
            //     let pos = self.node.convertToNodeSpaceAR(touch.getLocation());
            //     self.showEffect('click'+self.group, pos.x, pos.y);
            // }
        };
        // 绑定单点触摸事件
        this.clickListener = cc.eventManager.addListener(listenerObj, this.eventLayer);

        //处理服务器发来的请求
        this.initServerEvent();
    },

    // 战斗时websocket回调
    initServerEvent: function(){

        cc.eventCenter.GameStart.addListener((data, msg)=>{
            // 游戏开始
            self.room = msg.room;
            self.setRoom(msg.room);
            self.myName = msg.myName;self.enemyName = msg.enemyName;
            self.setPlayerNames(msg.myName, msg.enemyName);
            // self.setScores(msg.myScore, msg.enemyScore);
            self.group = msg.group;
            self.enemyGroup = msg.group=='G'?'B':(msg.group=='B'?'G':null);
            self.changeMap(msg.group);

            //选择终端卡
            self.selectTerminalCards(()=>{
                self.addChessChangeEvent();//棋子布局
                self.initTerminalBtn(self.group);//初始化terminal卡贴图
                //初始化终端卡使用状态
                for(let key in self.selectTerminal)
                    self.terminalSwitch[key] = false;
                //游戏开始音效
                self.playSound('begin');
            });
        });

        cc.eventCenter.GameFinish.addListener((data, msg)=>{
            // 游戏结束
            // 停止bgm回调并静音
            self.unschedule(self.bgmScheduleFunc);
            cc.audioEngine.stopAll();

            // 结束演出
            if(msg.winner == cc.UID)
            {
                self.setTips("游戏结束，我方获胜");
                // 展示胜利演出
                self.showEndEffect(msg.identify, true);
            }else{
                self.setTips('游戏结束，'+self.enemyName+'获胜');
                // 展示失败演出
                self.showEndEffect(msg.identify, false);
            }

            //设置标签：对手认输
            if(msg.name1 && msg.name2)
                self.setTips(msg.name1 +'已弃权，'+msg.name2 + '获胜！');

            // 9秒后返回开始场景
            self.schedule(function() {
                cc.director.loadScene('startScene');
            }, 9, 1);
        });

        cc.eventCenter.TurnStart.addListener((data, msg)=>{
            if(data.to != cc.UID)
                    return;

                // 回合开始
                self.setTips('你的回合，现在可以进行棋子移动');
                // 移除现有事件侦听
                self.removeAllBoardEvent();
                self.removeTerminalChoose();
                // 添加侦听
                self.addChessChooseEvent();
                self.addTerminalChoose();
        });

        cc.eventCenter.TurnEnd.addListener((data, msg)=>{
            if(data.to != cc.UID)
            return;
            // 回合结束
            self.turnEnd();
        });

        cc.eventCenter.LBCheck.addListener((data, msg)=>{
            // 超速回线 反馈
            if(data.to == cc.UID)
            {
                //己方
                if(msg.test)
                {
                    self.setTips('选择 Line Boost 对象\n再次点击终端卡 取消');
                    // 先取消其他侦听
                    self.removeAllBoardEvent();

                    let chesses = msg.target;
                    for(let key in chesses)
                    {
                        let target = self.myTeam[chesses[key]-1];
                        self.addLBEvent(target);
                    }
                }else{
                    // 音效
                    self.playSound('line');cc.log('unsetLB : ', msg.target);
                    // 摘除已装备的超速回线
                    self.setLineBoost(self.group, msg.target, false);
                    // 回合结束
                    self.turnEnd();
                }
            }else{
                //敌方
                if(!msg.test)
                {
                    // 音效
                    self.playSound('line');
                    // 摘除已装备的超速回线
                    self.setLineBoost(self.enemyGroup, msg.target, false);
                }
            }
        });
        cc.eventCenter.LBDone.addListener((data, msg)=>{
            // 音效
            self.playSound('line');
            self.playSound('lb');
            // 超速回线 确认
            if(data.to == cc.UID)
            {
                if(msg.test)
                {
                    // 装备超速回线
                    self.setLineBoost(self.group, msg.target, true);
                    // 回合结束
                    self.turnEnd();
                }else
                    cc.log(msg.error);
            }else{
                if(msg.test)
                {
                    // 装备超速回线
                    self.setLineBoost(self.enemyGroup, msg.target, true);
                    //确认对方使用终端卡
                    let enemyTerminalPanel = self.enemyTerminalPanel.getComponent('EnemyTerminalPanel');
                    enemyTerminalPanel.setShownTerminal('lineboost');
                }
            }
        });
        cc.eventCenter.FWCheck.addListener((data, msg)=>{
            // 防火墙 反馈
            if(data.to == cc.UID){
                if(msg.test)
                {
                    self.setTips('选择 Fire Wall 对象\n再次点击终端卡 取消');
                    // 先取消其他侦听
                    self.removeAllBoardEvent();

                    self.addFWEvent(msg.target);
                }else{
                    // 音效
                    self.playSound('wall');
                    // 移除己方现有防火墙
                    self.setFireWall(self.group, msg.target['x'], msg.target['y'], false);
                    // 回合结束
                    self.turnEnd();
                }
            }else{
                if(!msg.test)
                {
                    // 音效
                    self.playSound('wall');
                    // 移除己方现有防火墙
                    self.setFireWall(self.enemyGroup, 9-msg.target['x'], 9-msg.target['y'], false);
                }
            }
        });
        cc.eventCenter.FWDone.addListener((data, msg)=>{
            // 音效
            self.playSound('wall');
            self.playSound('fw');
            // 防火墙 确认
            if(data.to == cc.UID)
            {
                if(msg.test)
                {
                    // 添加wall
                    self.setFireWall(self.group, msg.target['x'], msg.target['y'], true);
                    // 回合结束
                    self.turnEnd();

                }else
                    cc.log(msg.error);
            }else{
                if(msg.test)
                {
                    // 添加wall
                    self.setFireWall(self.enemyGroup, 9-msg.target['x'], 9-msg.target['y'], true);
                    //确认对方使用终端卡
                    let enemyTerminalPanel = self.enemyTerminalPanel.getComponent('EnemyTerminalPanel');
                    enemyTerminalPanel.setShownTerminal('firewall');
                }
            }
        });
        cc.eventCenter.VCCheck.addListener((data, msg)=>{
            if(data.to != cc.UID)
                    return;

            // 探查 反馈
            if(msg.test)
            {
                self.setTips('选择 Virus Check 对象\n再次点击终端卡 取消');
                // 先取消其他侦听
                self.removeAllBoardEvent();
                
                let chesses = msg.target;
                for(let key in chesses)
                {
                    let target = self.enemyTeam[chesses[key]-1];
                    self.addVCEvent(target);
                }
            }else
                cc.log(msg.error);
        });
        cc.eventCenter.VCDone.addListener((data, msg)=>{
            // 音效
            self.playSound('check');
            self.playSound('vc');
            // 探查 结束
            if(data.to == cc.UID)
            {
                if(msg.test)
                {
                    self.setVirusCheck(self.enemyGroup, msg.target, msg.result);
                    // 回合结束
                    self.turnEnd();
                }else
                    cc.log(msg.error);
            }else{
                if(msg.test)
                    self.setVirusCheck(self.group, msg.target, msg.result);
                    //确认对方使用终端卡
                    let enemyTerminalPanel = self.enemyTerminalPanel.getComponent('EnemyTerminalPanel');
                    enemyTerminalPanel.setShownTerminal('viruscheck');
            }
        });
        cc.eventCenter.NFCheck.addListener((data, msg)=>{
            if(data.to != cc.UID)
                return;
            // 交换 反馈
            if(msg.test)
            {
                self.setTips('选择 两枚 404 Not Found 对象\n再次点击终端卡 取消');
                // 先取消其他侦听
                self.removeAllBoardEvent();

                // 清空记录notfound对象的静态变量
                ChessClass.nf_no1 = null;
                ChessClass.nf_no2 = null;
                    
                let chesses = msg.target;
                for(let key in chesses)
                {
                    let target = self.myTeam[chesses[key]-1];
                    self.addNFEvent(target);
                }
            }else
                cc.log(msg.error);
        });
        cc.eventCenter.NFDone.addListener((data, msg)=>{
            // 音效
            self.playSound('exchange');
            self.playSound('nf');
            // 交换 确认
            if(data.to == cc.UID)
            {
                if(msg.test)
                {
                    self.switchChess(self.group, msg.no1, msg.no2, msg.check);
                    // 回合结束
                    self.turnEnd();
                }else
                    cc.log(msg.error);
            }else{
                if(msg.test)
                {
                    self.switchChess(self.enemyGroup, msg.no1, msg.no2, msg.check);
                    //确认对方使用终端卡
                    let enemyTerminalPanel = self.enemyTerminalPanel.getComponent('EnemyTerminalPanel');
                    enemyTerminalPanel.setShownTerminal('notfound');
                }
            }
        });
        cc.eventCenter.RVCheck.addListener((data, msg)=>{
            //随机验证 反馈
            if(data.to != cc.UID)
            return;
            if(msg.test)
            {
                self.setTips('选择 一处 验证位置\n再次点击终端卡 取消');
                // 先取消其他侦听
                self.removeAllBoardEvent();
                // 给目标棋盘格加上标记
                self.randomPoses = msg.target;
                self.setRandoms(self.randomPoses, 1);
                //添加棋盘点击侦听
                self.addRVEvent(self.randomPoses);
            }else
                cc.log(msg.error);
        });
        cc.eventCenter.RVDone.addListener((data, msg)=>{
            //随机验证 确认
            // 音效
            self.playSound('Verification');
            self.playSound('rv');
            if(data.to == cc.UID)
            {
                if(msg.test)
                {
                    //显示特效
                    self.showEffect('myRv');
                    //标记最终选择的验证位置
                    self.setRandoms(new Array(self.VerificationPos), 2);
                    self.terminalSwitch['rv'] = true;//设置rv已使用
                    //记录随机验证出现点
                    if(self.group == 'G')
                        self.randomPosesG = msg.target;
                    else
                    self.randomPosesB = msg.target;
                    // 回合结束
                    self.turnEnd();
                }else
                    cc.log(msg.error);
            }else{
                if(msg.test)
                {
                    //翻转对方的棋盘坐标
                    for(let i in msg.target)
                    {
                        let pos = msg.target[i];
                        pos.x = 9-pos.x;
                        pos.y = 9-pos.y;
                    }
                    //显示特效
                    self.showEffect('enemyRv');
                    //向对方展示可能的验证位置
                    self.setRandoms(msg.target, 1);
                    //记录随机验证出现点
                    if(self.group == 'B')
                        self.randomPosesG = msg.target;
                    else
                        self.randomPosesB = msg.target;
                    //确认对方使用终端卡
                    let enemyTerminalPanel = self.enemyTerminalPanel.getComponent('EnemyTerminalPanel');
                    enemyTerminalPanel.setShownTerminal('randomverification');
                }
            }
        });
        cc.eventCenter.ZDACheck.addListener((data, msg)=>{
            // 零日攻击 反馈
            if(data.to == cc.UID)
            {
                //己方
                if(msg.test)
                {
                    self.setTips('选择 Zero-day Attack 对象\n再次点击终端卡 取消');
                    // 先取消其他侦听
                    self.removeAllBoardEvent();

                    let chesses = msg.target;
                    for(let key in chesses)
                    {
                        let target = self.myTeam[chesses[key]-1];
                        self.addZDAEvent(target);
                    }
                }
            }
        });
        cc.eventCenter.ZDADone.addListener((data, msg)=>{
            //零日攻击 确认
            // 音效
            self.playSound('zda');
            if(data.to == cc.UID)
            {
                cc.log('判断身份');
                if(msg.test)
                {
                    self.terminalSwitch['zda'] = true;//设置zda已使用
                    //记录选中棋子显示特效
                    let chess = self.myTeam[msg.target - 1];
                    self.playZDAAnime(chess);
                    //模拟棋子移动
                    self.onMoveChess(data, msg);
                }else
                    cc.log(msg.error);
            }else{
                if(msg.test)
                {
                    //记录选中棋子显示特效
                    let chess = self.enemyTeam[msg.target - 1];
                    self.playZDAAnime(chess);
                    //模拟棋子移动
                    self.onMoveChess(data, msg);
                    //确认对方使用终端卡
                    let enemyTerminalPanel = self.enemyTerminalPanel.getComponent('EnemyTerminalPanel');
                    enemyTerminalPanel.setShownTerminal('zerodayattack');
                }
            }
        });

        cc.eventCenter.SBCheck.addListener((data, msg)=>{
            // 沙盒测试 反馈
            if(data.to == cc.UID)
            {
                //己方
                if(msg.test)
                {
                    self.setTips('选择 SandBox Test 对象\n再次点击终端卡 取消');
                    // 先取消其他侦听
                    self.removeAllBoardEvent();

                    let chesses = msg.target;
                    //没有可以选择的对象时
                    if(chesses.length == 0)
                    {
                        //模拟再次按下沙盒测试终端卡取消效果
                        self.btCallFunc.onSandbox();
                        return;
                    }
                    for(let key in chesses)
                    {
                        let target = chesses[key];
                        if(target.group == self.group)
                        {
                            let targetChess = self.myTeam[target.no-1];
                            self.addSBEvent(targetChess);
                        }
                        else{
                            let targetChess = self.enemyTeam[target.no-1];
                            self.addSBEvent(targetChess);
                        }
                    }
                }
            }
        });
        cc.eventCenter.SBDone.addListener((data, msg)=>{
            //沙盒测试 确认
            // 音效
            self.playSound('sb');
            //装备的其他装备解除
            if(msg.target.removeLB)
            {
                self.setLineBoost(msg.target.group, msg.target.no, false);
                self.btCallFunc.passiveUnuseTerminal('lb');//被动解除终端卡
            }

            if(data.to == cc.UID)
            {
                if(msg.test)
                {
                    // 装备沙盒测试
                    self.setSandBox(msg.target.group, msg.target.no, true, true);
                    // 回合结束
                    self.turnEnd();
                }else
                    cc.log(msg.error);
            }else{
                if(msg.test)
                {
                    // 装备沙盒测试
                    self.setSandBox(msg.target.group, msg.target.no, true, false);
                    //确认对方使用终端卡
                    let enemyTerminalPanel = self.enemyTerminalPanel.getComponent('EnemyTerminalPanel');
                    enemyTerminalPanel.setShownTerminal('sandbox');
                }
            }
        });
        
        cc.eventCenter.SelectMove.addListener((data, msg)=>{
            if(data.to != cc.UID)
                return;
            // 棋子选择 反馈
            if(msg.test){
                self.setTips('选择 棋子移动目标');
                self.setPasses(msg.target);
            }
            else
                cc.log(msg.error);
        });
        cc.eventCenter.MoveDone.addListener(self.onMoveChess);
        cc.eventCenter.ShotBullet.addListener((data, msg)=>{
            // 弹幕
            // 对战玩家看不到游客弹幕
            if(msg.sender != 'V' || self.group == 'V')
                self.shotBullet(msg.str, msg.sender);
        });
        cc.eventCenter.RecvMap.addListener(self.returnMap);
        cc.eventCenter.SCCheck.addListener((data, msg)=>{});//Script confusion
        cc.eventCenter.SCDone.addListener((data, msg)=>{});
    },

    //加载声音pfb
    loadSound: function(callback)
    {
        // 加载sound
        cc.loader.loadRes("Prefab/Sound", (err, pfb) => {
            self.sound = cc.instantiate(pfb).getComponent('Sound');
            self.node.addChild(self.sound.node);
            self.curTag = 0;
            self.curBgm = 0;
            self.bgm = [self.sound.bgm01, self.sound.bgm02, self.sound.bgm03, 
                self.sound.bgm04, self.sound.bgm05, self.sound.bgm06];

            // 计时器循环播放背景音乐
            cc.audioEngine.stopMusic();
            self.bgmScheduleFunc = function(){
                if(cc.sys.localStorage.getItem('bgmSwitch') != 'true')
                    return;
                if(!cc.audioEngine.isMusicPlaying())
                {
                    cc.log('bgm播放', self.bgm.length);
                    if(self.bgm.length > self.curBgm)
                        cc.audioEngine.playMusic(self.bgm[self.curBgm++], false);
                    else{
                        self.curBgm = 0;
                        cc.audioEngine.playMusic(self.bgm[self.curBgm++], false);
                    }
                }
            };
            self.schedule(self.bgmScheduleFunc, 5);

            if(callback != null)
                callback();
        });
    },

    //通过棋盘还原对局
    returnMap : function(data, msg)
    {
        // 接收地图信息
        if(msg.test)
        {
            // 解析地图
            let mapData = JSON.parse(msg.map);
            let map = mapData.map;
            self.myName = msg.name1;self.enemyName = msg.name2;
            self.setPlayerNames(self.myName, self.enemyName);
            // self.setScores(msg.myScore, msg.enemyScore);
            self.group = msg.group;
            self.enemyGroup = msg.group=='G'?'B':(msg.group=='B'?'G':null);
            self.setRoom(msg.room);
            self.setCaptureState('G', mapData.GCaptureL, mapData.GCaptureV);
            self.setCaptureState('B', mapData.BCaptureL, mapData.BCaptureV);
            self.changeMap(msg.group);
            //修改游戏模式
            GAMEMODE = msg.gameMode;
            //保存终端卡
            self.terminalSwitch = msg.group == 'G' ? mapData.terminalG : mapData.terminalB;
            for(let i in self.terminalSwitch)
                self.terminalSwitch[i] = self.terminalSwitch[i] == 1 ? 0 : 1;
            self.selectTerminal = [];
            for(let key in self.terminalSwitch){
                self.selectTerminal.push(key);
                if(self.terminalSwitch[key] == 0)
                    self.terminalSwitch[key] = false;
                else 
                    self.terminalSwitch[key] = true;
            }
            self.initTerminalBtn(self.group);//初始化terminal卡贴图
            if(GAMEMODE > 0)
            {
                //初始化敌方使用的terminal卡贴图
                let enemyUsedTc;
                if(self.group == 'G')
                    enemyUsedTc = mapData.terminalUsedB;
                else 
                    enemyUsedTc = mapData.terminalUsedG;

                let enemyTerminalPanel = self.enemyTerminalPanel.getComponent('EnemyTerminalPanel');
                for(let i in enemyUsedTc)
                {
                    let tc = enemyUsedTc[i];
                    enemyTerminalPanel.setShownTerminalSimple(tc);
                }
            }
            //布置棋盘中棋子
            for(let i in map)
            {
                let obj = map[i];
                if(self.group == 'B'){
                    obj.x = 9-obj.x;
                    obj.y = 9-obj.y;
                }
                //对方棋子
                if(obj.group === self.enemyGroup){
                    if(obj.no){
                        let chess = self.enemyTeam[obj.no-1].getComponent("Chess");
                        chess.group = obj.group;
                        self.moveChess(obj.group, obj.no, obj.x, obj.y);
                        if(obj.show)
                            chess.changeType(obj.type);
                        if(obj.lineBoost)
                            self.setLineBoost(obj.group, obj.no, true);
                    }
                    //墙
                    else
                        self.setFireWall(obj.group, obj.x, obj.y, true);
                }else{
                    if(obj.no)
                    {
                        if(obj.no){
                            let chess = self.myTeam[obj.no-1].getComponent("Chess");
                            chess.group = obj.group;
                            self.moveChess(obj.group, obj.no, obj.x, obj.y);//设置位置
                            chess.changeType(obj.type, false);//设置身份可见性
                            if(obj.show)
                                chess.setCheckTag(true);
                            if(obj.lineBoost)
                                self.setLineBoost(obj.group, obj.no, true);
                        }
                    }
                    //墙
                    else
                        self.setFireWall(obj.group, obj.x, obj.y, true);
                }

            }
            //判断是否为自己回合
            if(msg.currentPlayer == 1)
            {
                // 回合开始
                self.setTips('你的回合，现在可以进行棋子移动');
                // 移除现有事件侦听
                self.removeAllBoardEvent();
                self.removeTerminalChoose();
                // 添加侦听
                self.addChessChooseEvent();
                self.addTerminalChoose();
            }else
                self.setTips('对手的回合');

            //音乐相关
            self.loadSound(()=>{
                self.playSound('begin');
            });

        }else{
            let popBox = self.pop.getComponent('Pop');
            popBox.show('dataFailed');
        }
    },

    // 结束游戏演出
    showEndEffect: function(identify, isWinner){
        // 翻开全部对方棋子
        for(let i = 0;i < identify.length;i++)
        {
            for(let k = 0;k < 8;k++)
            {
                let iden = identify[i];
                if(iden['group'] == self.enemyGroup){
                    let ec = self.enemyTeam[k].getComponent('Chess');
                    if(ec.grpNum == iden['no']){
                        ec.changeType(iden['type']);
                        break;
                    }
                }
            }
        }

        if(isWinner)
        {
            // 音效
            self.playSound('win');
        }else{
            // 音效
            this.playSound('lose');
        }
    },

    // 给己方棋子添加身份变化事件
    addChessChangeEvent: function(){
        // 给所有己方棋子添加类型选择
        for(let key in this.myTeam)
        {
            let node = this.myTeam[key].node;
            let chess = node.getComponent('Chess');
            let idTable = [];//用来记录身份的数组
            let call = (event)=>{
                    if(chess.type != 'virus' && this.vnum < 4)   //换帧
                    {
                        if(chess.type == 'link')
                            this.lnum--;
                        chess.changeType('virus', false);
                        this.vnum++;
                    }
                    else if(chess.type != 'link' && this.lnum < 4)
                    {
                        if(chess.type == 'virus')
                            this.vnum--;
                        chess.changeType('link', false);
                        this.lnum++;
                    }

                    if(this.vnum+this.lnum == 8)
                    {
                        this.gamestart = true;
                        cc.log('gamestart', this.gamestart);
                        this.setTips('请等待对手');
                        for(var key in this.myTeam){
                            let node = this.myTeam[key].node;
                            let chess = node.getComponent('Chess');

                            node.targetOff(this.node);

                            idTable.push(chess.type === 'link');
                        }
                        // 身份选择完毕后发送消息给服务器
                        this.sendData({'code':'22', 'name':'setted', data:{'idTable':idTable, 'terminals': this.selectTerminal}});
                    }
            }
            node.on(cc.Node.EventType.TOUCH_END, call, this.node);
        }
    },

    // 添加己方棋子移动侦听事件
    addChessChooseEvent: function(){
        // 给所有己方棋子添加类型移动选择
        for(let key in this.myTeam)
        {
            let node = this.myTeam[key].node;
            let chess = node.getComponent('Chess');
            let call = (event)=>{
                //动画播放时不允许点击
                if(this.tweenPlaying)
                    return;
                // 目标选择完毕后发送消息给服务器
                this.sendData({'code':'70', 'name':'get move target', data:{'no': chess.grpNum}});
            }
            node.on(cc.Node.EventType.TOUCH_END, call, node);
        }
    },

    // 添加终端卡使用权
    addTerminalChoose: function(){
        cc.log('启用终端卡');
        this.buttonBar.setTerminalPanelEnable(true);
    },

    // 移除终端卡使用权
    removeTerminalChoose: function(){
        cc.log('停用终端卡');
        this.buttonBar.setTerminalPanelEnable(false);
    },

    // 移除己方棋子上的侦听
    removeMyChessEvent: function(){
        for(let key in this.myTeam){
            let chess = this.myTeam[key].node;
            let script = chess.getComponent('Chess');

            chess.targetOff(chess);
            script.clearFocusTag();
        }
    },

    // 移除敌方棋子上的侦听
    removeEnemyChessEvent: function(){
        for(let key in this.enemyTeam){
            let chess = this.enemyTeam[key].node;
            let script = chess.getComponent('Chess');

            chess.targetOff(chess);
            script.clearFocusTag();
        }
    },

    // 给棋子加上lineboost选择事件
    addLBEvent: function(chess){
        let chessScript = chess.node.getComponent('Chess');
        chessScript.addLBEvent();
    },

    // 取消lineboost选择事件
    removeLBEvent: function(){
        // 取消所有棋子该类型侦听
        // 将棋子外貌恢复原样
        // 添加移动选择侦听
        this.removeEnemyChessEvent();
        this.removeMyChessEvent();
        this.addChessChooseEvent();
        this.setTips('选择要移动的棋子');
    },

    // 给棋子加上viruscheck选择事件
    addVCEvent: function(chess){
        let chessScript = chess.node.getComponent('Chess');
        chessScript.addVCEvent();
    },

    // 取消viruscheck选择事件
    removeVCEvent: function(){
        this.removeEnemyChessEvent();
        this.removeMyChessEvent();
        this.addChessChooseEvent();
        this.setTips('选择要移动的棋子');
    },

    // 给棋子加上404选择事件
    addNFEvent: function(chess){
        let chessScript = chess.node.getComponent('Chess');
        chessScript.addNFEvent();
    },

    // 取消404选择事件
    removeNFEvent: function(){
        this.removeEnemyChessEvent();
        this.removeMyChessEvent();
        this.addChessChooseEvent();
        this.setTips('选择要移动的棋子');
    },

    // 给棋子加上zero-day attack选择事件
    addZDAEvent: function(chess){
        let chessScript = chess.node.getComponent('Chess');
        chessScript.addZDAEvent();
    },

    // 给棋子加上sandbox test选择事件
    addZDAEvent: function(chess){
        let chessScript = chess.node.getComponent('Chess');
        chessScript.addZDAEvent();
    },

    // 取消zero-day attack选择事件
    removeZDAEvent: function(){
        // 取消所有棋子该类型侦听
        // 将棋子外貌恢复原样
        // 添加移动选择侦听
        this.removeEnemyChessEvent();
        this.removeMyChessEvent();
        this.addChessChooseEvent();
        this.setTips('选择要移动的棋子');
    },

    // 给棋子加上sandbox选择事件
    addSBEvent: function(chess){
        let chessScript = chess.node.getComponent('Chess');
        chessScript.addSBEvent();
    },

    // 解除sandbox事件侦听
    removeSBEvent:function(){
        this.removeEnemyChessEvent();
        this.removeMyChessEvent();
        this.addChessChooseEvent();
        this.setTips('选择要移动的棋子');
    },

    // 给棋盘加上firewall选择事件
    addFWEvent: function(limits){
        cc.log('添加fw选择事件');

        let listenerObj = {
            event: cc.EventListener.TOUCH_ONE_BY_ONE,
            onTouchBegan: function (touch, event) {return true; /*这里必须要写 return true*/},

            onTouchEnded: function (touch, event) {
                let pos = self.getBoardXY(touch.getLocation());
                cc.log('addFWEvent pos: ', pos);

                if(pos)
                {
                    let flag = true;
                    for(let i in limits) {
                        let limitPos = limits[i];
                        if(pos.x==limitPos['x'] && pos.y == limitPos['y'])
                        {
                            flag = false;
                            break;
                        }
                    };

                    if(flag){
                        // 建立wall
                        // 取消侦听
                        cc.log('移除fw侦听1', self.FWListener);
                        cc.eventManager.removeListener(self.FWListener);
                        self.FWListener = null;
                        self.sendData({'code':'42', 'name':'fireWall', data:{'x':pos.x, 'y':pos.y}});
                    }
                }
            }
        };
        // 绑定单点触摸事件
        this.FWListener = cc.eventManager.addListener(listenerObj, this.checkboard.node);
    },

    // 解除fire wall事件侦听
    removeFWEvent:function(){
        if(this.FWListener){
            cc.log('移除fw侦听2', this.FWListener);
            cc.eventManager.removeListener(this.FWListener);
            this.FWListener = null;
        }
        this.removeEnemyChessEvent();
        this.removeMyChessEvent();
        this.addChessChooseEvent();
        this.setTips('选择要移动的棋子');
    },

    //给棋盘加上random Verification选择事件
    addRVEvent: function(poses)
    {
        cc.log('添加rv选择事件');
        //隐藏己方所有棋子
        this.setMyChessesActive(false);

        let listenerObj = {
            event: cc.EventListener.TOUCH_ONE_BY_ONE,
            onTouchBegan: function (touch, event) {return true; /*这里必须要写 return true*/},

            onTouchEnded: function (touch, event) {
                let pos = self.getBoardXY(touch.getLocation());
                cc.log('addRVEvent pos: ', pos);

                if(pos)
                {
                    let flag = false;
                    for(let i in poses) {
                        let canSetPos = poses[i];
                        if(canSetPos.x==pos['x'] && canSetPos.y == pos['y'])
                        {
                            flag = true;
                            break;
                        }
                    };

                    if(flag){
                        // 建立探查点
                        // 取消侦听
                        cc.log('移除rv侦听1', self.RVListener);
                        cc.eventManager.removeListener(self.RVListener);
                        self.RVListener = null;
                        self.VerificationPos = pos;
                        self.sendData({'code':'202', 'name':'RandomVerification', data:{'x':pos.x, 'y':pos.y}});
                        //重新显示我方棋子
                        self.setMyChessesActive(true);
                    }
                }
            }
        };
        // 绑定单点触摸事件
        this.RVListener = cc.eventManager.addListener(listenerObj, this.checkboard.node);
    },

    setMyChessesActive: function(judge)
    {
        for(let i in this.myTeam)
        {
            let chess = this.myTeam[i].node;
            chess.active = judge;
        }
    },

    // 解除random Verification事件侦听
    removeRVEvent:function(){
        if(this.RVListener){
            cc.log('移除rv侦听2', this.RVListener);
            cc.eventManager.removeListener(this.RVListener);
            this.RVListener = null;
        }
        this.removeEnemyChessEvent();
        this.removeMyChessEvent();
        this.addChessChooseEvent();
        //移除随机验证标记
        this.setRandoms(self.randomPoses, 0);
        //重新显示我方棋子
        this.setMyChessesActive(true);
        this.setTips('选择要移动的棋子');
    },

    // 设置验证格标记
    setRandoms: function(poses, mode){
        cc.log('关闭所有通过效果');
        for(let key in this.myTeam){
            let script = this.enemyTeam[key].getComponent('Chess');
            script.clearFocusTag();
        }
        this.unsetPasses();

        cc.log('开启指定位置效果');
        for(let key in poses)
        {
            let pos = poses[key];
            cc.log('指定位置', pos['x'], pos['y']);
            let block = cc.find('line'+pos['y']+'/block'+pos['x'], this.checkboard.node).getComponent('block');
            block.setRandomVerification(mode);
        }
    },

    // 移除当前棋盘所有侦听
    removeAllBoardEvent: function(){
        cc.log('移除当前棋盘所有侦听');

        if(this.FWListener){
            cc.eventManager.removeListener(this.FWListener);
            this.FWListener = null;
        }
        if(this.RVListener){
            cc.eventManager.removeListener(this.RVListener);
            this.RVListener = null;
        }
        this.removeEnemyChessEvent();
        this.removeMyChessEvent();
        this.unsetPasses();
    },


    // 初始化terminal卡颜色
    initTerminalBtn: function(group){
        this.btCallFunc.initTerminalBtn(group, this.selectTerminal);
    },

    //初始化能使用的终端卡数
    // initTerminals: function()
    // {
    //     this.buttonBar.initTerminalBar();
    // },

    // 改变棋盘样式。不同阵营有不同的棋盘样式
    // @type: 阵营类别
    changeMap: function(type){
        
        this.group = type;

        let setChess = ()=>{
            // 给所有己方棋子改变类组别
            for(var key in this.myTeam)
            {
                let node = this.myTeam[key].node;
                let chess = node.getComponent('Chess');
                chess.changeGroup(type);
            }
            // 给所有对方棋子改变类组别
            for(var key in this.enemyTeam)
            {
                let node = this.enemyTeam[key].node;
                let chess = node.getComponent('Chess');
                chess.changeGroup(type=='G'?'B':'G');
            }
        };

        if(type == 'G'){
            SpriteLoader.load('checkboard1', sprite => {
                this.checkboard.spriteFrame = sprite;
            });
            SpriteLoader.load('stateBar1', sprite => {
                this.stateBar.spriteFrame = sprite;
                setChess();
            });
        }else{
            SpriteLoader.load('checkboard2', sprite => {
                this.checkboard.spriteFrame = sprite;
            });
            SpriteLoader.load('stateBar2', sprite => {
                this.stateBar.spriteFrame = sprite;
                setChess();
            });
        }
        
    },

    //选择terminal卡
    selectTerminalCards: function(callback){
        if(GAMEMODE == 0)
        {
            self.selectTerminal = ['lb', 'fw', 'vc', 'nf'];
            self.enemyTerminalPanel.active = false;
            if(callback != null)
                callback();
        }else{
            let selectTerminalPanel = self.selectTerminalPanel.getComponent('selectTerminal');
            selectTerminalPanel.init(self.group, callback);
            self.enemyTerminalPanel.active = true;
            let enemyTerminalPanel = self.enemyTerminalPanel.getComponent('EnemyTerminalPanel');
            enemyTerminalPanel.init(self.enemyGroup);
        }
    },
    
    // 显示确认框
    // @type: 确认框种类
    showPop: function(type){
        var pop = this.pop.getComponent('Pop');
        pop.show(type);
    },

    // 设置提示信息
    // @str: 提示信息文本
    setTips: function(str){
        this.tips.string = str;
    },

    // 设置房间号
    // @num: 房间号
    setRoom: function(num){
        var label = cc.find('room', this.stateBar.node).getComponent(cc.Label);
        label.string = num;
    },

    // 设置玩家名
    // @myName: 己方玩家名
    // @enemyName: 对方玩家名
    setPlayerNames: function(myName, enemyName){
        var label1 = cc.find('myName', this.stateBar.node).getComponent(cc.Label);
        var label2 = cc.find('enemyName', this.stateBar.node).getComponent(cc.Label);
        label1.string = myName;
        label2.string = enemyName;
    },

    // 设置玩家分数
    // @myName: 己方分数
    // @enemyName: 对方分数
    /*setScores: function(myScore, enemyScore){
        var label1 = cc.find('myScore', this.stateBar.node).getComponent(cc.Label);
        var label2 = cc.find('enemyScore', this.stateBar.node).getComponent(cc.Label);
        label1.string = myScore;
        label2.string = enemyScore;
    },*/

    // 设置终端卡剩余状态显示
    // @group: 组别
    // @cl: 捕获的link数
    // @cv: 捕获的virus数
    setCaptureState(group, cl, cv){
        var label;
        if(this.group == group)
            label = cc.find('myTerminalState', this.stateBar.node).getComponent(cc.Label);
        else
            label = cc.find('enemyTerminalState', this.stateBar.node).getComponent(cc.Label);
        label.string = 'Link: '+cl+' Virus: '+cv;
    },

    // 实现交换效果
    // @c1: 第一个指定棋子在数组中的下标+1
    // @c2: 第二个指定棋子在数组中的下标+1
    // @isSwitch: 是否交换
    switchChess: function(group, c1, c2, isSwitch){
        // 获得指定chess对象
        var mass = cc.instantiate(this.p_mass);
        var chess1, chess2, team;
        team = this.group==group?this.myTeam:this.enemyTeam;
        
        chess1 = team[c1-1].node; chess2 = team[c2-1].node;

        var c1Script = chess1.getComponent('Chess'), c2Script = chess2.getComponent('Chess');
        var pos1 = chess1.getPosition(), pos2 = chess2.getPosition();
        var seq1, seq2, func1, func2, switchEnd, lbSet1=false, lbSet2=false, sbSet1=false, sbSet2=false;

        // 记录两枚棋子装备lineboost的状况
        if(isSwitch)
        {
            if(c1Script.hasLineBoost)
                lbSet2=true;
            else if(c2Script.hasLineBoost)
                lbSet1=true;
        }else{
            if(c1Script.hasLineBoost)
                lbSet1=true;
            else if(c2Script.hasLineBoost)
                lbSet2=true;
        }
        // 记录两枚棋子装备sandBox的状况
        if(isSwitch)
        {
            if(c1Script.hasSandBox)
                sbSet2=true;
            else if(c2Script.hasSandBox)
                sbSet1=true;
        }else{
            if(c1Script.hasSandBox)
                sbSet1=true;
            else if(c2Script.hasSandBox)
                sbSet2=true;
        }

        // 回调函数用以去掉switch、check标记并重置敌方棋子至背面并设置line boost交换情况
        func1 = cc.callFunc(()=>{
            c1Script.setSwitchTag(false);

            if(this.group!=group)
                c1Script.changeTypeImmediately('bottom');
            else
                c1Script.setCheckTag(false);
            
                this.setLineBoost(group, c1, false);
                this.setSandBox(group, c1, false, false);
        }, this);
        func2 = cc.callFunc(()=>{
            c2Script.setSwitchTag(false);
            
            if(this.group!=group)
                c2Script.changeTypeImmediately('bottom');
            else
                c2Script.setCheckTag(false);

                this.setLineBoost(group, c2, false);
                this.setSandBox(group, c2, false, false);
        }, this);

        switchEnd = cc.callFunc(()=>{
            this.setLineBoost(group, c1, lbSet1);
            this.setLineBoost(group, c2, lbSet2);
            this.setSandBox(group, c1, sbSet1, false);
            this.setSandBox(group, c2, sbSet2, false);
            //取消动画进行标记
            this.tweenPlaying = false;
        });

        if(isSwitch){
            seq1 = cc.sequence(cc.spawn(c1Script.bezierMove(), func1), cc.moveTo(0.22, pos2), switchEnd);
            seq2 = cc.sequence(cc.spawn(c2Script.bezierMove(), func2), cc.moveTo(0.22, pos1));
        }else{
            seq1 = cc.sequence(cc.spawn(c1Script.bezierMove(), func1), cc.moveTo(0.22, pos1), switchEnd);
            seq2 = cc.sequence(cc.spawn(c2Script.bezierMove(), func2), cc.moveTo(0.22, pos2));
        }
        //添加动画进行标记
        this.tweenPlaying = true;
        // 开始演出
        this.node.addChild(mass);
        mass.setPosition(0, 0);
        chess1.runAction(seq1);
        chess2.runAction(seq2);
        
        if(this.group==group)
        {
            // 若是我方则设置nfSwitch为true
            this.terminalSwitch['nf'] = true;
        }
    },

    // 取消交换效果
    switchCancel: function(){
        this.removeNFEvent();//去掉交换标记
        let btCallFunc = this.btCallFunc;
        btCallFunc.terminalCardUsing == '';
        btCallFunc.nf.opacity = 255;
    },

    // 实现棋子移动
    // @group: 阵营/颜色
    // @c: 棋子在数组中的下标
    // @x, y: 移动坐标
    moveChess: function(group, c, x, y){
        cc.log('棋子移动', group, c, x, y);
        var chess = group==this.group?this.myTeam[c-1] : this.enemyTeam[c-1];
        if(y==0)
            x=++this.enemyServerSize;
        else if(y==9)
            x=++this.myServerSize;
        chess.getComponent('Chess').moveTo(x, y);
    },

    // 加速回线效果
    // @group: 组别
    // @c: 指定的棋子
    // @isSwitch: 开启还是关闭
    setLineBoost: function(group, c, isSwitch){
        var chess;
        if(this.group == group)
            chess = this.myTeam[c-1].node.getComponent('Chess');
        else
            chess = this.enemyTeam[c-1].node.getComponent('Chess');
        if(group == this.group)
            this.terminalSwitch['lb'] = isSwitch;
        chess.setLineBoost(isSwitch);
    },

    // 防火墙效果
    // @bx, by: 指定的空格位置坐标
    // @isSwitch: 开启还是关闭
    // @group: fireWall的种类
    setFireWall: function(group, bx, by, isSwitch){
        var board = this.checkboard.node;
        let block = cc.find('line'+by+'/block'+bx, board);

        if(group == this.group)
            this.terminalSwitch['fw'] = isSwitch;
        block.getComponent('block').setFireWall(isSwitch, group);
    },

    // 探查器效果
    // @group: 棋子的种类
    // @c: 指定的显示身份的棋子
    // @type: 棋子的真实身份
    setVirusCheck: function(group, c, type){
        let team = group==this.group?this.myTeam:this.enemyTeam;
        var chess = team[c-1].node.getComponent('Chess');
        
        if(group==this.group)
            chess.setCheckTag(true);
        else{
            chess.changeType(type);
            this.terminalSwitch['vc'] = true;
        }
    },

    // 可通过效果
    // @bx, by: 指定的空格位置坐标
    // @isSwitch: 开启还是关闭
    setBlockCanPass: function(bx, by, isSwitch){
        var board = this.checkboard.node;
        let block = cc.find('line'+by+'/block'+bx, board).getComponent('block');
        block.setCanPass(isSwitch);
    },

    // 设置选中棋子周围的可通过效果
    // @blocks: 记录可通过区域的数组
    setPasses: function(blocks){
        cc.log('关闭所有通过效果');
        for(let key in this.myTeam){
            let script = this.enemyTeam[key].getComponent('Chess');
            script.clearFocusTag();
        }
        this.unsetPasses();

        cc.log('开启指定位置效果');
        for(let key in blocks)
        {
            let pos = blocks[key];
            this.setBlockCanPass(pos['x'], pos['y'], true);
            cc.log('指定位置', pos['x'], pos['y']);

            if(pos['chess'])
                this.enemyTeam[pos['chess']-1].getComponent('Chess').setLockTag(true);
        }
    },

    unsetPasses: function(){
        // 关闭所有通过效果
        for(let i = 1;i <= 8;i++)
        {
            for(let j = 1;j <= 8;j++)
            {
                let block = cc.find('line'+i+'/block'+j, this.checkboard.node).getComponent('block');
                block.setCanPass(false);
            }
        }
        for(let k = 1;k<=2;k++)
        {
            let block0 = cc.find('line0/block'+k, this.checkboard.node).getComponent('block');
            block0.setCanPass(false);
            let block9 = cc.find('line9/block'+k, this.checkboard.node).getComponent('block');
            block9.setCanPass(false);
        }
    },

    // 零日攻击效果
    // @group: 组别
    // @c: 指定的棋子
    // @x, y: 坐标
    setZeroDayAttack: function(group, c, x, y){
        if(group == this.group)
            this.terminalSwitch['zda'] = true;
        //展示音效和特效
        //移动棋子
        this.moveChess(group, c, x, y);
    },

    // 沙盒测试效果
    // @group: 组别
    // @c: 指定的棋子
    // @judge: 装备/解除终端卡
    // @useTerminal: 是否为我方使用
    setSandBox: function(group, c, judge = true, useTerminal = false){
        if(judge)
        {
            let chess;
            if(this.group == group)
                chess = this.myTeam[c-1].node.getComponent('Chess');
            else
                chess = this.enemyTeam[c-1].node.getComponent('Chess');
            if(useTerminal)
                this.terminalSwitch['sb'] = true;
            chess.setSandBox(true);
        }
        else 
            self.removeSandBox(group, c);
    },

    //移除沙盒测试效果
    removeSandBox: function(group, c){
        let chess;
        if(this.group == group)
            chess = this.myTeam[c-1].node.getComponent('Chess');
        else
            chess = this.enemyTeam[c-1].node.getComponent('Chess');
        chess.setSandBox(false);
    },

    // 发送弹幕
    // @str: 要发送的弹幕内容
    // @group: 弹幕发送方，分为'G''B''V'三种
    shotBullet: function(str, group){
        
        var bullet = cc.instantiate(this.bullet);
        var scale = (Math.ceil(Math.random()*21) - 11) / 100 + 1;
        var winWidth = cc.winSize.width;
        var time = 3.5 + 0.12 * str.length;
        bullet.getComponent(cc.Label).string = str;
        bullet.width = str.length * 25 * scale;
        bullet.height = 40 * scale;

        switch(group){
            case 'G':
                bullet.color = cc.color(255, 255, 0);
                var ran = (Math.ceil(Math.random()*5) - 1) * (self.group == group ? -1 : 1);
                bullet.setPosition(winWidth / 2 + bullet.width / 2, 40*ran);
            break;
            case 'B':
                bullet.color = cc.color(0, 0, 255);
                var ran = (Math.ceil(Math.random()*5) - 1) * (self.group == group ? -1 : 1);
                bullet.setPosition(winWidth / 2 + bullet.width / 2, 40*ran);
            break;
            case 'V':
                bullet.color = cc.color(168, 168, 168);
                var ran = Math.ceil(Math.random()*9) - 5;
                bullet.setPosition(winWidth / 2 + bullet.width / 2, 40*ran);
            break;
        }
        var seq = cc.sequence(cc.moveBy(time, -winWidth - bullet.width, 0), cc.callFunc(()=>{bullet.removeFromParent();}));
        cc.log(str, time);
        this.node.addChild(bullet);
        bullet.runAction(seq);
    },

    // 发送消息给服务端
    sendData: function(cmd){

        // 若连接中断则重连后再发送消息
        if (!cc.webSocket || !(cc.webSocket instanceof WebSocket) || cc.webSocket.readyState !== WebSocket.OPEN) {
            // 记录当前待发送信息
            // this.toSendData = cmd;
            // 断开重连
            cc.webSocket.close();
            let pop = self.pop.getComponent('Pop');
            pop.show('socketClose');
        } else {
            cmd = Rson.encode(cmd);
            cc.log(cmd);
            cc.webSocket.send(cmd);
        };
    },

    showEffect: function(type, x, y){
        let p;
        switch(type){
            case 'honor':
                p = cc.instantiate(this.p_honor);
                this.checkboard.node.addChild(p);
                p.setPosition(this.convertBoardToNodeXY(x,y));

                this.playSound('link');
            break;

            case 'danger':
                p = cc.instantiate(this.p_danger);
                this.checkboard.node.addChild(p);
                p.setPosition(this.convertBoardToNodeXY(x,y));

                this.playSound('virus');
            break;

            case 'clickB':
                p = cc.instantiate(this.p_click_b);
                this.node.addChild(p);
                p.setPosition(x, y);

                this.playSound('click');
            break;

            case 'clickG':
                p = cc.instantiate(this.p_click_g);
                this.node.addChild(p);
                p.setPosition(x, y);

                this.playSound('click');
            break;

            case 'fire':
                p = cc.instantiate(this.p_fire);
                this.node.addChild(p);

                p.setPosition(x, y);
            break;

            case 'myRv':
                //给棋盘上我方棋子处显示rv特效 3秒后销毁
                let myTeam = this.myTeam;
                for(let i in myTeam)
                {
                    p = cc.instantiate(this.P_rv);
                    let chess = myTeam[i].node.getComponent('Chess');
                    if(chess.posY >= 1 && chess.posY <= 8)
                        chess.setTempEffect(p, 3);
                }
            break;

            case 'enemyRv':
                //给棋盘上敌方棋子处显示rv特效 3秒后销毁
                let enemyTeam = this.enemyTeam;
                for(let i in enemyTeam)
                {
                    p = cc.instantiate(this.P_rv);
                    let chess = enemyTeam[i].node.getComponent('Chess');
                    if(chess.posY >= 1 && chess.posY <= 8)
                        chess.setTempEffect(p, 3);
                }
            break;
            
        }
    },

    // 播放音效
    playSound: function(effect){
        //声音没加载完成时返回
        if(this.sound == null)
            return;
        //设置了不播放音效时返回
        if(!canSePlay)
            return;

        switch(effect){
            case 'link':
                cc.audioEngine.play(this.sound.e_link);
            break;

            case 'virus':
                cc.audioEngine.play(this.sound.e_virus);
            break;

            case 'line':
                cc.audioEngine.play(this.sound.e_line);
            break;

            case 'wall':
                cc.audioEngine.play(this.sound.e_wall);
            break;

            case 'check':
                cc.audioEngine.play(this.sound.e_check);
            break;

            case 'exchange':
                cc.audioEngine.play(this.sound.e_exchange);
            break;

            case 'Verification':
                cc.audioEngine.play(this.sound.e_Verification);
            break;

            case 'begin':
                cc.audioEngine.play(this.sound.e_begin);
            break;

            case 'move':
                cc.audioEngine.play(this.sound.e_move);
            break;

            case 'click':
                cc.audioEngine.play(this.sound.e_click);
            break;

            case 'lose':
                cc.audioEngine.play(this.sound.e_lose);
            break;

            case 'win':
                cc.audioEngine.play(this.sound.voice_win);
            break;

            case 'lb':
                cc.audioEngine.play(this.sound.voice_lb);
            break;

            case 'fw':
                cc.audioEngine.play(this.sound.voice_fw);
            break;

            case 'vc':
                cc.audioEngine.play(this.sound.voice_vc);
            break;

            case 'nf':
                cc.audioEngine.play(this.sound.voice_nf);
            break;

            case 'rv':
                cc.audioEngine.play(this.sound.voice_rv);
            break;

            case 'zda':
                cc.audioEngine.play(this.sound.voice_zda);
            break;

            case 'sb':
                cc.audioEngine.play(this.sound.voice_sb);
            break;
        }
    },

    // 将点击坐标转化为棋盘坐标
    getBoardXY: function(pos){
        let boardX=null, boardY=null;
        if(pos.y>=215 && pos.y<=775){
            boardX = Math.round((pos.x+7.5)/70);
            boardY = 9-Math.round((pos.y-180)/70);
        }

        if(boardX && boardY)
            return cc.p(boardX, boardY);
        else
            return null;
    },

    convertBoardToNodeXY: function(x, y){
        let nodeX=null, nodeY=null;
        if(y>=1 && y<=8){
            nodeX = -313 + 70*x;
            nodeY = 315 - 70*y;
        }

        if(nodeX && nodeY)
            return cc.p(nodeX, nodeY);
        else
            return null;
    },

    // 重新初始化websocket
    initWebSocket: function() {
        cc.log('重新连接服务器');
        this.reConnect = true;
        cc.webSocket = new WebSocket(SOCKET_ADDRESS);
        cc.webSocket.onmessage = this.onWSMsg;
    },

    // 回合结束时处理所有侦听
    turnEnd:function()
    {
        cc.log('回合结束');
        this.setTips('对手的回合');
        this.removeAllBoardEvent();
        this.removeTerminalChoose();
        this.btCallFunc.onTerminalUseFinish();

        this.sendData({'code':'91', 'name':'turnEnd', data:{}});
    },

    //移动棋子
    onMoveChess: function(data, msg)
    {
        // 音效
        self.playSound('move');
        // 棋子移动 确认
        if(data.to == cc.UID)
        {
            if(msg.test)
            {
                let result = msg.result;
                if(result['type'] != 3)
                    self.moveChess(self.group, msg.target, result['x'], result['y']);

                // 若移动模式为进攻（吃了别的棋子）则移除掉对应棋子
                if(result['type']==2){

                    //吃了正常棋子
                    if(result['eno'] != 0)
                    {
                        let script = self.enemyTeam[result['eno']-1].getComponent('Chess');
                        //清除sb以外的标记
                        script.clearAllTag('sb');

                        script.changeType(result['etype']);
                        self.setCaptureState(self.group, result['captureL'], result['captureV']);
                        
                        self.moveChess(self.enemyGroup, result['eno'], result['ex'], result['ey']);
                        // 显示吃子时的粒子特效
                        if(result['etype']=='link')
                            self.showEffect('honor', result['x'], result['y']);
                        else if(result['etype']=='virus')
                            self.showEffect('danger', result['x'], result['y']);

                        //吃子的棋子装备了SandBoxTest
                        if(result['sbOpen'])
                        {
                            //棋子翻面
                            let myChess = self.myTeam[msg.target-1].getComponent('Chess');
                            myChess.setCheckTag(true);
                        }

                        //吃的棋子装备了lb
                        if(result['moveLB'])
                        {
                            //吃的是对方棋子，自己这边不用表现
                        }
                    }
                }
                // 若是移入database
                if(result['type']==3){
                    // 按server现存棋子数移动棋子位置
                    self.moveChess(self.group, msg.target, 0, result['y']);

                    if(result['moveLB'])
                    {
                        self.terminalSwitch['lb'] = false;
                        
                        let btCallFunc = self.btCallFunc;
                        btCallFunc.terminalCardUsing == '';
                        btCallFunc.lb.opacity = 255;
                    }

                    let script = self.myTeam[msg.target-1].getComponent('Chess');
                    //清除sb以外的标记
                    script.clearAllTag('sb');
                }
                //如果触发了 [随机验证] 就把所有可能的验证标记移除
                if(result['verificated'])
                {
                    if(result['effectValication'] == 'G')
                    {
                        //消除一边的随机验证点
                        self.setRandoms(self.randomPosesG, 0);
                    }
                    else if(result['effectValication'] == 'B')
                    {
                        //消除一边的随机验证点
                        self.setRandoms(self.randomPosesB, 0);
                    }
                    else
                    {
                        //消除全部随机验证点
                        self.setRandoms(self.randomPosesG.concat(self.randomPosesB), 0);
                    }
                    //标记棋子身份已被探查
                    let script = self.myTeam[msg.target-1].getComponent('Chess');
                    script.setCheckTag(true);
                    //移除装备终端卡
                    if(result['rvRemoveLB'])
                    {
                        self.setLineBoost(self.group, msg.target, false);
                        self.btCallFunc.passiveUnuseTerminal('lb');
                    }
                    else if(result['rvRemoveSB'])
                    {
                        self.setSandBox(self.group, msg.target, false, false);
                    }
                }
                // 回合结束
                self.turnEnd();
            }else
                cc.log(msg.error);
        }
        else{
            if(msg.test)
            {
                let result = msg.result;
                if(result['type'] != 3)
                    self.moveChess(self.enemyGroup, msg.target, 9-result['x'], 9-result['y']);

                // 若移动模式为进攻（吃了别的棋子）则移除掉对应棋子
                if(result['type']==2){
                    
                    //吃了正常棋子
                    if(result['eno'] != 0)
                    {
                        self.setCaptureState(self.enemyGroup, result['captureL'], result['captureV']);
                        self.moveChess(self.group, result['eno'], 9-result['ex'],9-result['ey']);
                        // 显示吃子时的粒子特效
                            if(result['etype']=='link')
                            self.showEffect('honor', 9-result['x'], 9-result['y']);
                        else if(result['etype']=='virus')
                            self.showEffect('danger', 9-result['x'], 9-result['y']);

                        //自己被吃的子装了lb
                        if(result['moveLB'])
                        {
                            self.terminalSwitch['lb'] = false;

                            let btCallFunc = self.btCallFunc;
                            btCallFunc.terminalCardUsing == '';
                            btCallFunc.lb.opacity = 255;
                        }

                        //吃子的棋子装备了SandBoxTest
                        if(result['sbOpen'])
                        {
                            //棋子翻面
                            let script = self.enemyTeam[msg.target-1].getComponent('Chess');
                            script.changeType(result['sbOpen']);
                        }
                    }

                }else if(result['type']==3){
                    // 按server现存棋子数移动棋子位置
                    self.moveChess(self.enemyGroup, msg.target, 0, 9-result['y']);

                    let script = self.enemyTeam[msg.target-1].getComponent('Chess');
                    //清除sb以外的标记
                    script.clearAllTag('sb');
                }
                //如果触发了 [随机验证] 就把所有可能的验证标记移除
                if(result['verificated'])
                {
                    if(result['effectValication'] == 'G')
                    {
                        //消除一边的随机验证点
                        self.setRandoms(self.randomPosesG, 0);
                    }
                    else if(result['effectValication'] == 'B')
                    {
                        //消除一边的随机验证点
                        self.setRandoms(self.randomPosesB, 0);
                    }
                    else
                    {
                        //消除全部随机验证点
                        self.setRandoms(self.randomPosesG.concat(self.randomPosesB), 0);
                    }
                    //棋子翻到正面
                    let script = self.enemyTeam[msg.target-1].getComponent('Chess');
                    script.changeType(result['moveType']);
                    //移除装备终端卡
                    if(result['rvRemoveLB'])
                    {
                        self.setLineBoost(self.enemyGroup, msg.target, false);
                    }
                    else if(result['rvRemoveSB'])
                    {
                        self.setSandBox(self.enemyGroup, msg.target, false, false);
                    }
                }
            }
        }
    },

    //播放zero-day Attack动画
    playZDAAnime: function(target)
    {
        if(this.zdaAnime == null)
            this.zdaAnime = cc.find('Canvas/fitLayer/ZeroDayAnime').getComponent(cc.Animation);
        this.zdaAnime.node.active = true;
        //移动到合适的坐标
        let worldPos = target.node.parent.convertToWorldSpaceAR(target.node.position);
        let localPos = this.zdaAnime.node.parent.convertToNodeSpaceAR(worldPos);
        this.zdaAnime.node.x = localPos.x;
        //播放动画
        this.zdaAnime.play();
    },
});